home *** CD-ROM | disk | FTP | other *** search
- /* ----------------------------------------------------------------
- * argv.c
- *
- * $Header: /private/postgres/src/utils/fmgr/RCS/argv.c,v 1.4 1991/03/04 13:56:10 mao Exp $
- * ----------------------------------------------------------------
- */
-
- #include <ctype.h>
- #include <stdio.h>
-
- /***********************************************************************
- **
- ** These routines build argv's. An "argv" is a null-terminated array
- ** of pointers to strings. Argv's are often declared as char** or
- ** char* foo [];
- **
- ** char***
- ** argv_new()
- **
- ** returns a structure which is a "scaffold" for building up
- ** an argv. At any point, the structure will contain an argv in its
- ** first field. If it overflows, a new, larger one is substituted,
- ** and the old one discarded. So don't keep direct references to the argv
- ** unless you are not going to put any more stuff into it.
- **
- ** Say
- ** char*** scaffold = (char***)argv_new();
- **
- ** Then, when the argv is completed, dereference it...
- **
- ** char** complete_argv = *scaffold;
- **
- ** Then free the scaffold if you wish...
- **
- ** cfree(scaffold);
- **
- ** The argv itself is also allocated by calloc, and may be cfree()'d when
- ** it is no longer needed.
- **
- ** argv_new() returns 0 if it runs out of memory.
- **
- **
- ** int
- ** argv_put(scaffold, arg)
- ** char*** scaffold;
- ** char* arg;
- **
- ** puts an additional arg into an argv, increasing the size
- ** if necessary. Returns 0 on success, -1 if it runs out of memory.
- **
- ** char**
- ** argv_from_str(str)
- ** char* str
- **
- ** Parses a string and builds an argv from it. It
- ** recognizes quote-marks and escapes (\).
- **
- ** For example,
- **
- ** foo bar "foo bar" '\'foo\'' '"foo"'
- **
- ** gets parsed into
- **
- ** foo
- ** bar
- ** foo bar
- ** 'foo'
- ** "foo"
- ** (0)
- **
- ** The argv and its components are all allocated by calloc().
- ** Returns 0 if it runs out of memory.
- **
- **
- ************************************************************************/
-
-
-
- struct argv_rec
- { char** value;
- int size;
- int place;
- };
-
-
- argv_put(argv, str)
- struct argv_rec * argv;
- char* str;
- {
- if (argv->place + 1 == argv->size) /* oops.. overflow. */
- {
- char** old_argv = argv->value;
- int old_size = argv->size;
-
- argv->size = argv->size *2;
- argv->value = (char**)calloc(1, argv->size*sizeof(char*));
- if(argv->value == 0) { return -1; }
- bcopy(old_argv, argv->value, old_size * sizeof(char*));
- free(old_argv);
- }
-
- argv->value[argv->place] = str;
- argv->place++;
-
- return 0;
-
- }
-
-
- struct argv_rec *
- argv_new()
- {
- struct argv_rec* retval =
- (struct argv_rec*) calloc(1,sizeof(struct argv_rec));
- if (retval == 0) return 0;
-
- retval->value = (char**)calloc(1, 2*sizeof(char*));
- if(retval->value == 0) { free(retval); return 0; }
-
- retval->size = 2;
- retval->place = 0;
-
- return retval;
- }
-
-
- static char*
- strip(strp)
- char** strp;
- {
- char* str = strp? *strp: 0;
- char* buffer;
- char quote = 0;
- char* next_p;
-
- if(str == 0 || *str == 0) return 0;
-
- buffer = (char*)malloc(strlen(str)+1);
- if(buffer == 0) return 0;
-
- next_p = buffer;
-
- while (isspace(*str)) str++;
-
- if(*str == '\'' || *str == '"' ) quote = *str++;
-
- while(*str && !(isspace(*str) && !quote) && !(quote && *str == quote))
- {
- if(*str == '\\') str++;
- *next_p++ = *str++;
- }
-
- if(*str && (quote && *str == quote) ) str++; /* skip end-quote */
-
- *next_p = 0;
- { char* retval = (char*)calloc(1, strlen(buffer) +1 );
- if (retval) sprintf(retval, "%s", buffer);
- free(buffer);
- *strp = str;
- return retval;
- }
- }
-
-
- char**
- argv_from_str(str)
- char* str;
- {
- struct argv_rec* argv;
- char* next_arg;
- extern errno;
-
- errno = 0;
-
- argv = argv_new();
- if(argv == 0) return 0;
-
- while( (next_arg = strip(&str)) != 0)
- { argv_put(argv, next_arg);
- }
-
- { char** retval = argv->value;
- free(argv);
- return retval;
- }
-
-
- }
-
- fprintf_argv(fp,argv)
- FILE * fp;
- char** argv;
- {
- if(argv)
- while(*argv) fprintf(fp, "%s\n", *argv++);
- }
-
- printf_argv(argv)
- char** argv;
- {
- if(argv)
- while(*argv) printf("%s\n", *argv++);
- }
-
- int strcmp();
-
- static
- alcomp(p,q)
- char**p;
- char**q;
- {
- return strcmp(*p,*q);
- }
-
- sort_argv(argc, argv)
- char** argv;
- {
-
- qsort(argv, argc, sizeof(char*), alcomp );
-
- }
-
-
- #undef testing
- #ifdef testing
- #include <stdio.h>
- main(argc, argv)
- char** argv;
- {
- char buf[256];
- char** argy;
- int argk = 0;
- char** aargh;
- scanf("%[^\n]", buf);
- argy = argv_from_str(buf);
-
- aargh = argy;
-
- while(*argy) { printf("%s\n", *argy++ ); }
- {
- char** p = aargh;
- while(*p++) argk++;
- }
- sort_argv(argk, aargh);
- while(*aargh) { printf("%s\n", *aargh++ ); }
- fflush(stdout);
- }
- #endif testing
-